package com.volunteer.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redis类
 *
 * @author willow
 * @version v.0.1
 * @date 2018年08月2日
 */
@Component
public class RedisComponent {

    private final static Logger logger = LoggerFactory.getLogger(RedisComponent.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    // 获取object类型的value值
    public Object getObject(Object key) {
        return redisTemplate.opsForValue().get(key);
    }

    // 根据key移除redis
    public void removeObject(String key) {
        stringRedisTemplate.delete(key);
    }

    // 批量移除
    public void delKeys(List<String> keyList) {
        Set<String> keys = new HashSet<>(keyList);
        redisTemplate.delete(keys);
    }

    // 指定缓存失效时间
    public boolean expire(String key, long time, TimeUnit timeUnit) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, timeUnit);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 根据key 获取过期时间
    public long getExpire(String key, TimeUnit timeUnit) {
        return redisTemplate.getExpire(key, timeUnit);
    }

    /**
     * String类型
     **/
    // 获取string类型的value值
    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    // 添加redis(永久存储)
    public void putString(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    // 添加redis(自定义有效时长，分钟为单位)
    public void putString(String key, String value, int timeout) {
        putString(key, value, timeout, TimeUnit.MINUTES);
    }

    // 添加redis(自定义有效时长，自定义单位)
    public void putString(String key, String value, int timeout, TimeUnit unit) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    /**
     * Hash类型
     **/

    // 获取hash类型的value值
    public Object getHashObject(String key, String hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    // 移除hash类型的记录
    public void removeHashObject(String key, String hashKey) {
        redisTemplate.opsForHash().delete(key, hashKey);
    }

    // 判断hash类型的记录是否存在
    public boolean hasHashObject(String key, String hashKey) {
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    // 添加hash类型的记录
    public void putHashObject(String key, String hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    /**
     * List类型
     */

    // 获取List类型的对象
    public List getListObject(String key, int start, int end) {
        return redisTemplate.opsForList().range(key, start, end);
    }

    // 添加List类型的记录
    public void putListObject(String key, List list) {
        redisTemplate.opsForList().rightPushAll(key, list);
    }

    public static synchronized RedisComponent getInstance() {
        return new RedisComponent();
    }

    private RedisTemplate getRedisTemplate() {
        if (redisTemplate == null) {
            redisTemplate = ApplicationContextHolder.getBean("redisTemplate");
            RedisSerializer stringSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringSerializer);
            redisTemplate.setValueSerializer(stringSerializer);
            redisTemplate.setHashKeySerializer(stringSerializer);
            redisTemplate.setHashValueSerializer(stringSerializer);
            this.redisTemplate = redisTemplate;
        }
        return redisTemplate;
    }
}
